package com.easyjava.builder;

import com.easyjava.bean.Constants;
import com.easyjava.bean.FieldInfo;
import com.easyjava.bean.TableInfo;
import com.easyjava.utils.MyStringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: 小闹心
 * @Description: query生成器
 * @DateTime: 2024/11/17 13:05
 **/
public class BuildQuery {
    private static final Logger logger = LoggerFactory.getLogger(BuildQuery.class);
    public static void execute(TableInfo tableInfo){
        File folder = new File(Constants.PATH_QUERY);
        if(!folder.exists()){
            folder.mkdirs();
        }
        String className = tableInfo.getBeanName() + Constants.SUFFIX_BEAN_QUERY;
        File file = new File(folder, className + ".java");
        OutputStream out = null;
        OutputStreamWriter outWriter = null;
        BufferedWriter bw = null;
        try{
            out = new FileOutputStream(file);
            outWriter = new OutputStreamWriter(out, StandardCharsets.UTF_8);
            bw = new BufferedWriter(outWriter);
            bw.write("package " + Constants.PACKAGE_QUERY + ";");
            bw.newLine();
            bw.newLine();
            List<FieldInfo> fieldEnumList = tableInfo.getFieldEnumList();
            for(FieldInfo fieldInfo : fieldEnumList){
                bw.write("import " + Constants.PACKAGE_ENUMS + "." + MyStringUtils.upperCaseFirstLetter(fieldInfo.getPropertyName() + "Enum;"));
                bw.newLine();
            }
            if(tableInfo.getHaveDate() || tableInfo.getHaveDateTime()){
                bw.write("import java.util.Date;");
                bw.newLine();
            }
            if(tableInfo.getHaveBigDecimal()){
                bw.write("import java.math.BigDecimal;");
                bw.newLine();
            }
            bw.newLine();
            bw.newLine();
            // 生成类注释
            BuildComment.createClassComment(bw,tableInfo.getComment());
            bw.write("public class " + className + " extends BaseParam {");
            bw.newLine();
            List<FieldInfo> extendField = new ArrayList<>();
            // 生成属性
            for(FieldInfo fieldInfo : tableInfo.getFieldList()){
                BuildComment.createFieldComment(bw,fieldInfo.getComment());
                bw.write("\tprivate " + fieldInfo.getJavaType() + " " + MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + ";");
                bw.newLine();
                // 判断是否有String类型
                if(ArrayUtils.contains(Constants.SQL_STRING_TYPES,fieldInfo.getSqlType())){
                    bw.write("\tprivate " + fieldInfo.getJavaType() + " " + MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + Constants.SUFFIX_BEAN_QUERY_FUZZY + ";");
                    bw.newLine();
                    FieldInfo tempInfo = new FieldInfo();
                    tempInfo.setJavaType(fieldInfo.getJavaType());
                    tempInfo.setPropertyName(MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + Constants.SUFFIX_BEAN_QUERY_FUZZY);
                    extendField.add(tempInfo);
                }
                // 是否有日期类型
                if(ArrayUtils.contains(Constants.SQL_DATE_TIMES_TYPES,fieldInfo.getSqlType()) || ArrayUtils.contains(Constants.SQL_DATE_TYPES,fieldInfo.getSqlType())){
                    FieldInfo tempInfo = new FieldInfo();
                    tempInfo.setJavaType("String");
                    tempInfo.setPropertyName(MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + Constants.SUFFIX_BEAN_QUERY_TIME_START);
                    extendField.add(tempInfo);
                    bw.write("\tprivate " + tempInfo.getJavaType() + " " + tempInfo.getPropertyName() + ";");
                    bw.newLine();
                    tempInfo = new FieldInfo();
                    tempInfo.setJavaType("String");
                    tempInfo.setPropertyName(MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + Constants.SUFFIX_BEAN_QUERY_TIME_END);
                    extendField.add(tempInfo);
                    bw.write("\tprivate " + tempInfo.getJavaType() + " " + tempInfo.getPropertyName() + ";");
                    bw.newLine();
                }
                extendField.add(fieldInfo);
            }
            bw.newLine();
            // getter and setter
            for(FieldInfo field : extendField){
                String tempField = MyStringUtils.upperCaseFirstLetter(field.getPropertyName());
                bw.write("\tpublic void set" + tempField + "(" + field.getJavaType() + " " + MyStringUtils.lowerCaseFirstLetter(field.getPropertyName()) + ") {");
                bw.newLine();
                bw.write("\t\tthis."+MyStringUtils.lowerCaseFirstLetter(field.getPropertyName()) + " = " + MyStringUtils.lowerCaseFirstLetter(field.getPropertyName()) + ";");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();

                bw.write("\tpublic " + field.getJavaType() + " get" + tempField + "() {");
                bw.newLine();
                bw.write("\t\treturn " + MyStringUtils.lowerCaseFirstLetter(field.getPropertyName()) + ";");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();
            }
            bw.write("}");
            bw.flush();
        }catch (Exception e){
            logger.error("创建QUERY对象失败");
        }finally {
            if(bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outWriter != null){
                try {
                    outWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
